package database

import (
	"encoding/json"
	"reflect"
	"testing"
	"weak"
	// "gitcode.com/OpenDictionary/wiktionary2sql/database"
)

type wordData struct {
	word          string `w2s:"NOT NULL,PRIMARY KEY,INDEX"`
	abbreviations []string
	antonyms      []string
	synonyms      []string
	langCode      *string `w2s:"NOT NULL,INDEX"`
	phonetic      [2]string
	translations  []translationData
}

type translationData struct {
	langCode string `w2s:"INDEX,NOT NULL"`
	meaning  string `w2s:"NOT NULL"`
}

func TestFieldReflection(t *testing.T) {
	// Test cases for field reflection
	var type_of_wordData = reflect.TypeFor[wordData]()
	var res, err = NewTableSchema(type_of_wordData)
	if err != nil {
		t.Errorf("Error creating table schema: %v", err)
	}

	var wordDataSchema = TableSchema{
		Name: "wordData",
		Kind: Struct,
		Attributes: map[string]SqlColumnAttr{
			"word": SqlColumnAttr{
				Type: String,
				Constraints: map[ColumnConstraint]struct{}{
					NotNull:    {},
					PrimaryKey: {},
					Index:      {},
				},
			},
			"langCode": SqlColumnAttr{
				Type: String,
				Constraints: map[ColumnConstraint]struct{}{
					NotNull: {},
					Index:   {},
				},
			},
		},
		SubSchemas: make(map[string]*TableSchema),
	}
	var abbreviationSchema TableSchema
	{
		var str_abbreviations = "abbreviations"
		var workDataSchemaWeak = weak.Make(&wordDataSchema)

		abbreviationSchema = TableSchema{
			Name:       "slice",
			Kind:       Slice,
			ListType:   ListType{Kind: String, Table: nil},
			Attributes: make(map[string]SqlColumnAttr),
			SubSchemas: make(map[string]*TableSchema),
			Parent_schema: &InParentSchema{
				Field_name:   &str_abbreviations,
				Table_schema: workDataSchemaWeak,
			},
		}
		wordDataSchema.SubSchemas[str_abbreviations] = &abbreviationSchema
	}
	var antonyms TableSchema
	{
		var str_antonyms = "antonyms"
		var workDataSchemaWeak = weak.Make(&wordDataSchema)

		antonyms = TableSchema{
			Name:       "slice",
			Kind:       Slice,
			ListType:   ListType{Kind: String, Table: nil},
			Attributes: make(map[string]SqlColumnAttr),
			SubSchemas: make(map[string]*TableSchema),
			Parent_schema: &InParentSchema{
				Field_name:   &str_antonyms,
				Table_schema: workDataSchemaWeak,
			},
		}
		wordDataSchema.SubSchemas[str_antonyms] = &antonyms
	}
	var synonyms TableSchema
	{
		var str_synonyms = "synonyms"
		var workDataSchemaWeak = weak.Make(&wordDataSchema)

		synonyms = TableSchema{
			Name:       "slice",
			Kind:       Slice,
			ListType:   ListType{Kind: String, Table: nil},
			Attributes: make(map[string]SqlColumnAttr),
			SubSchemas: make(map[string]*TableSchema),
			Parent_schema: &InParentSchema{
				Field_name:   &str_synonyms,
				Table_schema: workDataSchemaWeak,
			},
		}
		wordDataSchema.SubSchemas[str_synonyms] = &synonyms
	}

	var phonetic TableSchema
	{
		var str_phonetic = "phonetic"
		var workDataSchemaWeak = weak.Make(&wordDataSchema)

		phonetic = TableSchema{
			Name:       "array",
			Kind:       Array,
			ListType:   ListType{Kind: String, Table: nil},
			Attributes: make(map[string]SqlColumnAttr),
			SubSchemas: make(map[string]*TableSchema),
			Parent_schema: &InParentSchema{
				Field_name:   &str_phonetic,
				Table_schema: workDataSchemaWeak,
			},
		}
		wordDataSchema.SubSchemas[str_phonetic] = &phonetic
	}

	var translationsSlice TableSchema
	var translationData TableSchema
	{
		var str_translationData = "translationData"
		var str_translations = "translations"
		var workDataSchemaWeak = weak.Make(&wordDataSchema)
		var translationsSchemaWeak = weak.Make(&translationsSlice)

		translationData = TableSchema{
			Name: str_translationData,
			Kind: Struct,
			Attributes: map[string]SqlColumnAttr{
				"langCode": SqlColumnAttr{
					Type: String,
					Constraints: map[ColumnConstraint]struct{}{
						Index:   {},
						NotNull: {},
					}},
				"meaning": SqlColumnAttr{
					Type: String,
					Constraints: map[ColumnConstraint]struct{}{
						NotNull: {},
					}},
			},
			SubSchemas: make(map[string]*TableSchema),
			Parent_schema: &InParentSchema{
				Field_name:   nil,
				Table_schema: translationsSchemaWeak,
			},
		}

		translationsSlice = TableSchema{
			Name:       "slice",
			Kind:       Slice,
			ListType:   ListType{Table: &translationData},
			Attributes: make(map[string]SqlColumnAttr),
			SubSchemas: make(map[string]*TableSchema),
			Parent_schema: &InParentSchema{
				Field_name:   &str_translations,
				Table_schema: workDataSchemaWeak,
			},
		}
		wordDataSchema.SubSchemas[str_translations] = &translationsSlice
	}

	// judge if res == wordDataSchema

	res_json, _ := json.Marshal(res)
	wordDataSchema_json, _ := json.Marshal(wordDataSchema)
	if string(res_json) != string(wordDataSchema_json) {
		t.Errorf("Expected: %s", string(wordDataSchema_json))
		t.Errorf("Actual: %s", string(res_json))
	} else {
		t.Logf("Expected: %s", string(wordDataSchema_json))
		t.Logf("Actual: %s", string(res_json))
	}

}
